/*******************************************************************
 * Copyright (c) 2013 珠海比特讯科技有限公司. All rights reserved.
 * （1）软件的版权将受到法律保护，不允许非经授权的使用；
 * （2）未经版权所有人授权，任何人不得修改、复制和传播软件源代码、图片及其它资源等；
 * （3）未经版权所有人授权，不允许对软件进行修改；
 * （4）未经版权所有人授权，不允许在该软件的基础上开发新的软件；
 * （5）珠海比特讯科技有限公司拥有最终解释权
 *******************************************************************/
package youxiao.bytezon.configs;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import youxiao.bytezon.configs.security.auth.CustomAuthenticationProvider;
import youxiao.bytezon.configs.security.jwt_filters.JWTAuthenticationFilter;
import youxiao.bytezon.configs.security.jwt_filters.JWTLoginFilter;

@Configuration
@EnableWebSecurity
class WebSecurityConfig extends WebSecurityConfigurerAdapter {
	
	@Autowired CustomAuthenticationProvider authenticationProvider;

	// 设置 HTTP 验证规则
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.headers()
		    .frameOptions()
		    .sameOrigin()
		    .and()
		    // disable CSRF, http basic, form login
		    .csrf().disable()
		    // 跨域支持
		    .cors().and()
		    .httpBasic().disable()
		    .formLogin().disable()
		    // ReST is stateless, no sessions
        // .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
				// 对请求进行认证
		    .authorizeRequests()
		    // 所有 / 的所有请求 都放行
		    .antMatchers("/").permitAll()
		    // 所有 /login 的POST请求 都放行
		    .antMatchers(HttpMethod.POST, "/login").permitAll()
		    // 定义/hello需要AUTH_WRITE权限检查
		    .antMatchers("/hello").hasAuthority("AUTH_WRITE")
		    // 定义/world需要ADMIN角色检查
		    .antMatchers("/world").hasRole("ADMIN")
		    // 所有请求需要身份认证
		    .anyRequest().authenticated().and()
		    // 添加一个过滤器 所有访问 /login 的请求交给 自定义JWTLoginFilter 来处理 这个类处理所有的JWT相关内容
		    // 登录测试（返回token）：
		    // curl -H "Content-Type: application/json" -X POST -d '{"username":"admin","password":"123456"}' http://127.0.0.1:8080/login
		    .addFilterBefore(new JWTLoginFilter("/login", authenticationManager()), UsernamePasswordAuthenticationFilter.class)
		    // 添加一个过滤器验证其他请求的Token是否合法
		    // Token验证：
		    // curl -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJhdXRob3JpdGllcyI6IlJPTEVfQURNSU4sQVVUSF9XUklURSIsInN1YiI6ImFkbWluIiwiZXhwIjoxNDkzNzgyMjQwfQ.HNfV1CU2CdAnBTH682C5-KOfr2P71xr9PYLaLpDVhOw8KWWSJ0lBo0BCq4LoNwsK_Y3-W3avgbJb0jW9FNYDRQ" http://127.0.0.1:8080/users
		    .addFilterBefore(new JWTAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
	}

	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		// 验证身份（用户名+密码）, 并定义了用户的权限。
		// Here build the "/login" filter's Authentication Manager
		auth.authenticationProvider(authenticationProvider);
	}
}
